package client;

import java.awt.BorderLayout;
import java.io.File;
import java.io.IOException;
import java.net.ConnectException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Vector;

import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.swing.Box;
import javax.swing.JPanel;

import sameClasses.Bytehandler;
import sameClasses.Crypter;
import sameClasses.EncryptedData;
import sameClasses.NetworkPacket;
import sameClasses.Plugin;
import sameClasses.User;

public class PluginManager {
  
  private Vector<Plugin> pluginlist;
  static mainFrame myFrame;
  static Client myClient;
  
  public PluginManager(mainFrame frame, Client client) {
    try {
      PluginManager.myFrame = frame;
      this.myClient = client;
      this.pluginlist = PluginLoader.loadPlugins(new File("./plugins"));
    } catch (IOException e) {
      e.printStackTrace();
    }
    for(Plugin elem:this.pluginlist) {
      myFrame.addTabToFrame(elem);
    }
    final Runtime r = Runtime.getRuntime();
    r.gc();
  }

  // Clientseitige Implementierung des serverseitigen Speicherns
  public static boolean storeOnServer(Plugin plugin) throws ConnectException {
    // http://www.javafaq.nu/java-article236.html
    
    EncPwAndSalt tmp = mainFrame.getMyPwAndSalt();
    boolean ret = false;
    try {
      ret = (Boolean) ((NetworkPacket) myClient.sendToServer(new NetworkPacket(plugin.getUser(), plugin.getId(), 2, Crypter.encrypt(tmp.getPassword(), tmp.getSalt(), Bytehandler.pluginDataToBytes(plugin.getList()))))).getData();
    } catch (IOException e) {
    }
    return ret;
  }

  //Clientseitige Implementierung des serverseitigen Ladens
  public static Object loadFromServer(Plugin plugin) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException, IOException {
    EncPwAndSalt tmp = mainFrame.getMyPwAndSalt();
    EncryptedData enc = null;
      enc = (EncryptedData) ((NetworkPacket) myClient.sendToServer(new NetworkPacket(plugin.getUser(), plugin.getId(), 1, new byte[0]))).getData();
    if(enc.getIV().length==16) {
      return Crypter.decrypt(tmp.getPassword(), tmp.getSalt(), enc);
    }
	return new byte[0];
  }

  public void stop() throws ConnectException {
    for (Plugin elem : pluginlist) {
      PluginManager.storeOnServer(elem);
    }
    Runtime r = Runtime.getRuntime();
    r.gc();
  }
  
  /*
  public JPanel gui(User user) {
    JPanel panel = new JPanel();
    panel.setLayout(new BorderLayout(0, 0));
    Box verticalBox = Box.createVerticalBox();
    panel.add(verticalBox);
    final Runtime r = Runtime.getRuntime();
    for(Plugin elem:this.pluginlist) {
      myFrame.addTabToFrame(elem);
    }
    r.gc();
    return panel;
  }
  */
    
  public void removeTabs() {
    for(Plugin elem:this.pluginlist) {
      myFrame.delTabFromFrame(elem);
    }
  }
  
  // vorher drin gewesen: Plugins als Checkboxen mit ihrem Namen direkt daneben anzeigen lassen in separatem JPanel
  // durch Klick auf eine Checkbox wurde das jeweilige Plugin aktiviert bzw. deaktiviert
    /*NetworkPacket packet = (NetworkPacket) Client.sendToServer(new NetworkPacket(user, 0, 1, 0));
    final Vector<Plugin> plugins = (Vector<Plugin>) packet.getData();
    if(plugins instanceof Vector) {
      for (final Object elem : plugins) {
        if(elem instanceof Plugin) {
          final JCheckBox pluginCheckbox = new JCheckBox(((Plugin) elem).getName());
          pluginCheckbox.addItemListener(new ItemListener() {
            @Override
            public void itemStateChanged(ItemEvent e) {
              if(pluginCheckbox.isSelected()) {
                for(Plugin pluginelem : plugins) {
                  if(((Plugin) elem).getId()==pluginelem.getId()) {
                    window.addTabToFrame(pluginelem);
                  }
                }
              } else {
                for(Plugin pluginelem : plugins) {
                  if(((Plugin) elem).getId()==pluginelem.getId()) {
                    window.delTabFromFrame(pluginelem);
                  }
                }
                r.gc();
                System.out.println(((Plugin) elem).getName()+"-Plugin stopped - invoking Garbage Collector");
              }
            }
          });
          verticalBox.add(pluginCheckbox);
        }
      }
    }*/

}
